#include "Alice/Core/Game.h"
#include "Alice/Resource/Path.hpp"
#include "Alice/Components/TextureComp.hpp"
#include "Alice/Components/TransformComp.hpp"
#include "Alice/Components/ColorComp.hpp"
#include "Alice/Components/ForceComp.hpp"
#include "Alice/Systems/ForceSys.h"
#include "Alice/Systems/TextureRenderSys.h"
#include "Alice/Systems/OBBSys.h"
#include "Alice/Components/AABBComp.hpp"
#include "Alice/Systems/SpriteAnimRenderSys.h"
#include "Alice/Components/SpriteAnimComp.hpp"
#include "Alice/Graphs/Brush.h"
#include "Alice/Systems/VisualBoxSys.h"
#include "Alice/Components/OBBComp.hpp"
#include "Alice/Components/VisualBoxComp.hpp"

namespace Alice
{

int Game::s_count = 0;

Game::Game()
{
    s_count += 1;

    assert(
        s_count < 2 && "Creating two Game instances is not allowed!"
    );

    m_world = std::make_unique<World>();
    m_window_mngr = std::make_unique<WindowMngr>();
    m_res_mngr = std::make_unique<ResourceMngr>();
    m_refl_mngr = std::make_unique<ReflMngr>();

    m_looping = false;
    m_playing = false;

    game_state = GameState::UNINIT;
}

Game::~Game()
{
    // 销毁窗口资源
    m_window_mngr->Destroy();
    // 清理资源管理器内的所有资源
    m_res_mngr->Clear();
}

bool Game::Init(WindowInfo window_info)
{
    // 初始化日志工具
    Log::Init();
    // 初始化四叉树
    m_world->InitQuadTree(window_info);
    // 初始化窗口
    bool ret = m_window_mngr->Init(window_info);
    //  注册窗口关闭事件
    m_world->GetEventMngr()->AddListener(
        Event(WINDOW_QUIT),
        [this](Event& event) {
            this->Quit();
        }
    );

    m_looping = true;
    m_playing = true;

    game_state = GameState::INITED;

    // 加载预置着色器
    m_res_mngr->LoadShader("default", 
        Path::GeneratePath(A_SHADER, "default_vertex.glsl").c_str(),
        Path::GeneratePath(A_SHADER, "default_fragment.glsl").c_str()
    );
    m_res_mngr->LoadShader("sprite_default", 
        Path::GeneratePath(A_SHADER, "sprite_default_vertex.glsl").c_str(),
        Path::GeneratePath(A_SHADER, "sprite_default_fragment.glsl").c_str()
    );

    // 注册纹理渲染系统
    // 使用临时实体绑定对应组件以获取签名
    Entity texture_rendered_entity = m_world->CreateEntity();
    m_world->AtachComp<TextureComp>(texture_rendered_entity, TextureComp{});
    m_world->AtachComp<TransformComp>(texture_rendered_entity, TransformComp{});
    m_world->AtachComp<ColorComp>(texture_rendered_entity, ColorComp{});
    // 注册
    m_world->RegisterSys<TextureRenderSys>(texture_rendered_entity);
    // 设置渲染系统使用的着色器
    m_world->GetSys<TextureRenderSys>()->SetShader(m_res_mngr->GetShader("sprite_default"));
    // 移除临时实体
    m_world->DestroyEntity(texture_rendered_entity);

    // 注册力系统
    Entity gravity_entity = m_world->CreateEntity();
    m_world->AtachComp<TransformComp>(gravity_entity, TransformComp{});
    m_world->AtachComp<ForceComp>(gravity_entity, ForceComp{});
    m_world->RegisterSys<ForceSys>(gravity_entity);
    m_world->DestroyEntity(gravity_entity);

    // 注册 OBB 碰撞系统
    Entity obb_entity = m_world->CreateEntity();
    m_world->AtachComp<TransformComp>(obb_entity, TransformComp{});
    m_world->AtachComp<OBBComp>(obb_entity, OBBComp{});
    m_world->RegisterSys<OBBSys>(obb_entity);
    m_world->DestroyEntity(obb_entity);

    // 注册精灵动画渲染系统
    Entity anim_rendered_entity = m_world->CreateEntity();
    m_world->AtachComp<SpriteAnimComp>(anim_rendered_entity, SpriteAnimComp{});
    m_world->AtachComp<TransformComp>(anim_rendered_entity, TransformComp{});
    m_world->AtachComp<ColorComp>(anim_rendered_entity, ColorComp{});
    m_world->RegisterSys<SpriteAnimRenderSys>(anim_rendered_entity);
    m_world->GetSys<SpriteAnimRenderSys>()->SetShader(m_res_mngr->GetShader("sprite_default"));
    m_world->DestroyEntity(anim_rendered_entity);

    // 注册可视化盒子系统
    Entity box = m_world->CreateEntity();
    m_world->AtachComp<TransformComp>(box, TransformComp{});
    m_world->AtachComp<OBBComp>(box, OBBComp{});
    m_world->AtachComp<VisualBoxComp>(box, VisualBoxComp{});
    m_world->RegisterSys<VisualBoxSys>(box);
    m_world->GetSys<VisualBoxSys>()->SetShader(m_res_mngr->GetShader("default"));
    m_world->GetSys<VisualBoxSys>()->GetShader().Use().SetVec3f("BoxColor", 0.94f, 0.94f, 1.0f);
    m_world->GetSys<VisualBoxSys>()->SetWindowInfo(window_info);
    m_world->DestroyEntity(box);

    return ret;
}

void Game::Start()
{
    assert(game_state == GameState::INITED &&
        "The game has not been initialized!");

    m_world->Before();
    while (m_looping)
    {
        // 窗口处理输入事件
        m_window_mngr->ProcessEvents(m_world->GetEventMngr());
        // 清空上一帧的内容
        m_window_mngr->ClearBuffer();
        // 更新世界内容
        m_world->Update();
        // 更新窗口渲染内容
        m_window_mngr->Update();
    }
    m_world->After();
}

void Game::Play()
{
    m_playing = true;
}

void Game::Pause()
{
    m_playing = false;
}

void Game::Quit()
{
    m_looping = false;
}

} // namespace Alice
